import arrow
import traceback

from queue import Queue
from threading import Thread
from copy import deepcopy
from pymongo import MongoClient

from conf.settings import CLOUDMONITOR_MONGODB, CLOUDMONITOR_DB

from utility.log import Logger
from utility.monitor import Monitor
from utility.enums import NotificationType

logger = Logger().get_logger()

db = MongoClient(CLOUDMONITOR_MONGODB)[CLOUDMONITOR_DB]


class T(Thread):
    def __init__(self, t_id, idx, total, q: Queue):
        self.task_id_list = deepcopy(t_id)
        self.q = q
        self.idx = idx
        self.total = total
        super(T, self).__init__()

    def run(self) -> None:
        for x in range(3):
            try:
                params = {
                    "notify_type_name": NotificationType.NT_ACTION_REPEAT.value,
                    "task": {
                        "addition": {
                            "task_id_list": self.task_id_list
                        }
                    }
                }
                resp = Monitor().post("/api/v2/notify", params)
                if isinstance(resp, dict):
                    logger.info(resp)
                elif resp and resp.status_code == 200:
                    logger.info("Send to celery.")
                    logger.info(f"{self.idx}/{self.total}")
                    break
            except Exception:
                traceback.print_exc()
        self.q.get()
        self.q.task_done()


def get_tasks_to_repeat(query):
    task_id_list = []
    i = 0
    for task in db.tasks.find(query, {'_id': 1}):
        task_id_list.append(str(task.get('_id')))
        i += 1

    total = i

    logger.info(f"Find {total} items.")

    q = Queue(maxsize=20)

    cache = []
    for idx, _id in enumerate(task_id_list):
        cache.append(_id)
        if len(cache) >= 5:
            q.put(idx)
            T(cache, idx, total, q).start()
            cache = []

    if cache:
        q.put(total)
        T(cache, total, total, q).start()

    q.join()


def main():
    logger.info(f"Start {__file__}")
    start_datetime = arrow.now().shift(hours=-24*7).datetime

    query = [
        {
            'status': {'$in': ['waiting', 'active']},
            'taskType': {'$in': ['vul', 'ssl', 'content', 'securityEvent']},
            'endTime': {'$gt': start_datetime, '$lt': arrow.now().shift(hours=-36).datetime}
        }, {
            'status': {'$in': ['waiting', 'active']},
            'taskType': {'$in': ['http', 'ping']},
            'endTime': {'$gt': start_datetime, '$lt': arrow.now().shift(hours=-1).datetime}
        }, {
            "status": "stopped", "progress": 100, "taskType": {"$in": ["http", "ping"]}
        }
    ]
    for q in query:
        get_tasks_to_repeat(q)

    logger.info(f"End {__file__}")


if __name__ == '__main__':
    main()
